package logic

import (
	"context"
	"fmt"
	"math/rand"
	table "pd/server/app/pd/data/order"
	productTable "pd/server/app/pd/data/product"
	userTable "pd/server/app/pd/data/user"
	form "pd/server/app/pd/form/order"
	model "pd/server/app/pd/model/order"
	"pd/server/com"
	"pd/server/plugin/logger"
	"time"
)

var orderTable table.OrderTable

type OrderLogic struct {
}

// GenerateOrderNumber 生成唯一订单号
func GenerateOrderNumber(prefix string) string {
	now := time.Now()
	datePart := now.Format("20060102")                  // 年月日
	timePart := now.Format("150405")                    // 时分秒
	randomPart := fmt.Sprintf("%04d", rand.Intn(10000)) // 4位随机数
	orderNumber := fmt.Sprintf("%s%s%s%s", prefix, datePart, timePart, randomPart)
	return orderNumber
}

func (this *OrderLogic) Create(ctx context.Context, frm *form.CreateOrderForm) (err error) {
	now := time.Now()
	frm.CreateTime = now
	frm.LastUpdateTime = now
	for _, item := range frm.Products {
		item.CreateTime = now
	}
	frm.OrderNo = GenerateOrderNumber("")
	frm.Status = model.OrderStatusPendingDelivery
	if frm.DeliveryPersonId != 0 {
		frm.Status = model.OrderStatusInProgress
	}
	frm.Source = model.SourceManualEntry
	err = orderTable.Create(ctx, frm)
	return
}

func (this *OrderLogic) Update(ctx context.Context, frm *form.CreateOrderForm) (err error) {
	return orderTable.Update(ctx, frm)
}

func (this *OrderLogic) Delete(ctx context.Context, frm *model.OrderModel) (err error) {
	return orderTable.Delete(ctx, frm)
}

func (this *OrderLogic) OrderList(ctx context.Context, frm *form.OrderListForm) (orderList []*model.OrderNode, total int64, err error) {
	if orderList, total, err = orderTable.OrderList(ctx, frm); err != nil {
		return
	}
	productIds := com.IdSet{}
	userIds := com.IdSet{}
	for _, order := range orderList {
		userIds.Add(order.DeliveryPersonId)
		for _, item := range order.Products {
			productIds.Add(item.ProductId)
		}
	}

	wg := com.AsyncFunc{}
	wg.Add(func() {
		users, e := (&userTable.UserTable{}).GetUserBatch(ctx, userIds.Slice())
		if e != nil {
			logger.Error(e)
			return
		}
		for _, order := range orderList {
			if tmp := users[order.DeliveryPersonId]; tmp != nil {
				order.DeliveryPerson = tmp.RealName
			}
		}
	})
	wg.Add(func() {
		products, e := (&productTable.ProductTable{}).GetProductBatch(ctx, productIds.Slice())
		if e != nil {
			logger.Error(e)
			return
		}
		for _, order := range orderList {
			for _, item := range order.Products {
				if tmp := products[item.ProductId]; tmp != nil {
					item.ProductName = tmp.Name
				}
			}
		}
	})

	wg.Wait()
	return
}
